using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using Unity.Collections;
using UnityEngine;

namespace TrainSystem
{
    public class Train : MonoBehaviour
    {
        public float speed = 5f;  // 最大移动速度
        public float accelerationTime = 2f;  // 从0加速到最大速度需要的时间
        public float decelerationTime = 1.5f;  // 从最大速度减速到0需要的时间
        public float pathCheckDistance = 0.5f;  // 提前检测下一个路径的距离
        [SerializeField] private float directionThreshold = 0.6f; // 选择方向需要的最小输入量

        public float currentSpeed = 0f;  // 当前实际速度
        public TrackPoint plannedNextPoint; // 预定的下一个路径点
        public TrackPoint currentPoint;  // 当前轨道点
        public TrackPoint nextPoint;    // 下一个轨道点
        public TrackPoint previousPoint;//上一个轨道点
        private Vector3 moveDirection;    // 实际移动方向
        public bool isMoving = false;   // 是否在移动

        public bool IsStopMove = false; // 是否强制停止移动
        public bool IsCanLevel = false;
        public int IsCanLevelIndex = 0;

        public int TrainLevel = 0;
        public List<TrainCarriage> TrainCarriages = new List<TrainCarriage>();
        public List<GameObject> Daos = new List<GameObject>();
        public List<GameObject> daos1 = new List<GameObject>();

        public GameObject Effect;
        
        private void Start()
        {
            if (currentPoint == null)
            {
                Debug.LogError("Train needs a starting track point!");
                return;
            }
            
            // 初始位置设置在当前轨道点
            transform.position = currentPoint.transform.position;
            moveDirection = Vector3.zero;
            isMoving = false;
            nextPoint = null;  // 等待输入来决定下一个点
            previousPoint = null;

            TrainCarriages[TrainLevel].OpenModel();
            Daos[TrainLevel].gameObject.SetActive(true);
            Daos[TrainLevel+1].gameObject.SetActive(true);
            daos1[TrainLevel].gameObject.SetActive(true);
            daos1[TrainLevel+1].gameObject.SetActive(true);

            GameEntry.Instance.JoystickUI.OnPointerUpAction += JoystickOnPointerUpEvent;

            EventManager.Instance.Subscribe(LevelTown1CompleteEvent.EventId,Leave1TownCompleteCallBack);
            EventManager.Instance.Subscribe(LevelTrainCompleteEvent.EventId,LevelTrainCompleteCallBack);
            EventManager.Instance.Subscribe(LevelTown2CompleteEvent.EventId,Level2TownCompleteCallBack);
        }

        private void Update()
        {
            if (nextPoint == null)
            {
                return;
            };

            if (IsStopMove) //如果处于强制停止状态，则所有数据清空
            {
                nextPoint = null;
                moveDirection = Vector3.zero;
                currentSpeed = 0f;
                isMoving = false;
            }
            // 更新速度
            if (isMoving)
            {
                // 加速
                currentSpeed = Mathf.MoveTowards(currentSpeed, speed, speed * Time.deltaTime / accelerationTime);
            }
            else
            {
                // 减速
                currentSpeed = Mathf.MoveTowards(currentSpeed, 0, speed * Time.deltaTime / decelerationTime);
            }

            // 只有有速度时才移动
            if (currentSpeed > 0)
            {
                // 移动火车
                float step = currentSpeed * Time.deltaTime;
                transform.position = Vector3.MoveTowards(transform.position, nextPoint.transform.position, step);

                // 平滑转向移动方向
                if (moveDirection != Vector3.zero)
                {
                    Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
                    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, step * 2);
                }

                // 检查是否到达下一个轨道点
                if (Vector3.Distance(transform.position, nextPoint.transform.position) < 0.1f)
                {
                    // 更新当前点
                    previousPoint = currentPoint;
                    currentPoint = nextPoint;

                    transform.position = currentPoint.transform.position; // 确保精确位置
                    if (currentPoint.IsStop)
                    {
                        IsStopMove = true;
                        IsCanLevel = true;
                        IsCanLevelIndex = currentPoint.LevelIndex;
                        CanLevelEvent canLevelEvent = new CanLevelEvent();
                        EventManager.Instance.Fire(this,canLevelEvent);
                        OpenTutoriseEvent  openTutoriseEvent = new OpenTutoriseEvent();
                        EventManager.Instance.Fire(this,openTutoriseEvent);
                        return;
                    }

                    if (currentPoint.IsDead)
                    {
                        FailEvent failEvent = new FailEvent();
                        EventManager.Instance.Fire(this,failEvent);
                        GameEntry.Instance.JoystickUI.IsCanMove = false;
                    }

                    // 如果有预定的下一个点，使用它
                    if (plannedNextPoint != null)
                    {
                        nextPoint = plannedNextPoint;
                        moveDirection = (nextPoint.transform.position - transform.position).normalized;
                        plannedNextPoint = null;
                    }
                    else if (isMoving)
                    {
                        // 尝试保持当前方向
                        TrackPoint potentialNext = GetNextInDirection(moveDirection);
                        if (potentialNext != null)
                        {
                            nextPoint = potentialNext;
                            moveDirection = (nextPoint.transform.position - transform.position).normalized;
                        }
                        else
                        {
                            // 没找到合适的点，停止移动
                            nextPoint = null;
                            moveDirection = Vector3.zero;
                            currentSpeed = 0f;
                            isMoving = false;
                        }
                    }
                    else
                    {
                        nextPoint = null;
                        moveDirection = Vector3.zero;
                    }
                }
            }
        }

        private TrackPoint GetNextInDirection(Vector3 direction)
        {
            foreach (var point in currentPoint.nextPoints)
            {
                if (point == null || point == currentPoint) continue;
                
                Vector3 pointDirection = (point.transform.position - transform.position).normalized;
                float directionMatch = Vector3.Dot(direction, pointDirection);
                
                // 如果方向足够接近（夹角小于30度），则选择该点
                if (directionMatch > 0.866f) // cos(30°) ≈ 0.866
                {
                    return point;
                }
            }
            return null;
        }

        public void EmergencyBrake()
        {
            currentSpeed = 0f;
            isMoving = false;
        }

        public void SetDirection(Vector2 inputDir)
        {
            if (currentPoint == null) return;
            if (IsStopMove)
            {
                return;
            }
            
            // 如果输入太小，忽略它
            if (inputDir.magnitude < 0.1f)
            {
                plannedNextPoint = null;
                isMoving = false;
                return;
            }

            // 将2D输入方向转换为3D方向
            Vector3 direction = new Vector3(inputDir.x, 0, inputDir.y);
            
            // 根据当前状态选择处理方式
            if (!isMoving)
            {
                if (nextPoint == null)
                {
                    TrackPoint bestPoint = FindBestNextPoint(currentPoint, direction, inputDir.magnitude);
                    if (bestPoint != null)
                    {
                        nextPoint = bestPoint;
                    }
                }
                else
                {
                    moveDirection = (nextPoint.transform.position - transform.position).normalized;
                    isMoving = true;
                    IsCanLevel = false;
                    DontLevelEvent dontLevelEvent = new DontLevelEvent();
                    EventManager.Instance.Fire(this,dontLevelEvent);
                }
                // 开始新的移动
            }
            else if (nextPoint != null)
            {
                float distanceToNext = Vector3.Distance(transform.position, nextPoint.transform.position);
                // Debug.LogError(distanceToNext);
                // 在接近下一个点时检查方向变化，但只记录决定
                if (distanceToNext < pathCheckDistance)
                {
                    TrackPoint newNextPoint = FindBestNextPoint(nextPoint, direction, inputDir.magnitude);
                    if (newNextPoint != null)
                    {
                        Vector3 newDirection = (newNextPoint.transform.position - nextPoint.transform.position).normalized;
                        // Debug.LogError(Vector3.Dot(moveDirection, newDirection));
                        // 记录决定，但不立即执行
                        if (Vector3.Dot(moveDirection, newDirection) < 0.866f)
                        {
                            plannedNextPoint = newNextPoint;
                        }
                    }
                }
            }
        }

        private TrackPoint FindBestNextPoint(TrackPoint fromPoint, Vector3 direction, float inputMagnitude)
        {
            if (inputMagnitude < directionThreshold) return null;
            
            TrackPoint bestPoint = null;
            float bestMatchValue = -1f;
            
            foreach (var point in fromPoint.nextPoints)
            {
                if (point == null || point == fromPoint || point == previousPoint) continue;
                
                Vector3 pointDirection = (point.transform.position - fromPoint.transform.position).normalized;
                float directionMatch = Vector3.Dot(direction, pointDirection);

                // 选择最匹配的方向
                if (directionMatch > bestMatchValue && directionMatch > 0.5f)
                {
                    // 检查是否是后退方向
                    if (moveDirection != Vector3.zero)
                    {
                        float forwardAngle = Vector3.Angle(moveDirection, pointDirection);
                        if (forwardAngle > 150f) continue; // 跳过后退方向
                    }
                    
                    bestMatchValue = directionMatch;
                    bestPoint = point;
                }
            }
            
            return bestPoint;
        }

        public TrackPoint GetNextPoint()
        {
            return nextPoint;
        }

        private void JoystickOnPointerUpEvent()
        {
            if (IsStopMove)
            {
                IsStopMove = false;
            }
        }

        private void Leave1TownCompleteCallBack(object sender,EventArgs ea)
        {

            int Previousindex =  GameEntry.Instance.trackPointManager.trackPoints1.IndexOf(previousPoint);

            currentPoint = GameEntry.Instance.trackPointManager.trackPoints2[0];
            previousPoint = GameEntry.Instance.trackPointManager.trackPoints2[Previousindex];
        }

        private void Level2TownCompleteCallBack(object sender,EventArgs ea)
        {
            int Previousindex =  GameEntry.Instance.trackPointManager.trackPoints2.IndexOf(previousPoint);
            int currentindex = GameEntry.Instance.trackPointManager.trackPoints2.IndexOf(currentPoint);

            currentPoint = GameEntry.Instance.trackPointManager.TrackPoints3[currentindex];
            previousPoint = GameEntry.Instance.trackPointManager.TrackPoints3[Previousindex];
        }

        private async void LevelTrainCompleteCallBack(object sender,EventArgs ea)
        {
            if (TrainLevel == 2)
            {
                return;
            }

            TrainLevel += 1;
            if (TrainLevel == 1)
            {
                TrainCarriages[TrainLevel].OpenModel();
            }
            else if(TrainLevel == 2)
            {
                TrainCarriages[TrainLevel].OpenModel();
                TrainCarriages[TrainLevel+1].OpenModel();
            }
            Daos[TrainLevel + 1].gameObject.SetActive(true);
            daos1[TrainLevel + 1].gameObject.SetActive(true);
            
            Effect.gameObject.SetActive(true);

            await Task.Delay(1000);
            Effect.gameObject.SetActive(false);
        }
    }
}